/**
  * @file    :SeqStack.hpp
  * @brief   :顺序栈的模板类
  * @author  :TMJ
  * @version :V1.0.0
  * @date    :2023-12-27
*/

#ifndef _STACK_SEQSTACK_H_
#define _STACK_SEQSTACK_H_

#include "Stack.hpp"
#include <iostream>

template<typename type>
class SeqStack;

template<typename type>
std::ostream &operator<<(std::ostream &os, SeqStack<type> &seq_stack);


template<typename type>
class SeqStack : public Stack<type> {

    friend std::ostream &operator<<<>(std::ostream &os, SeqStack<type> &seq_stack);

public:
    // 指定容量的构造函数
    SeqStack(int capacity = 20) : m_capacity(capacity), m_top(-1) {
        if (capacity < 0) {
            throw std::invalid_argument("容量大小异常!");
        }

        this->m_data = new type[capacity];
        if (!this->m_data) {
            throw std::bad_alloc();
        }
    }

    // 析构函数
    ~SeqStack();

    // 判断栈满
    bool IsFull() const;

    // 清空栈元素
    void Clear();

    // 入栈
    virtual bool Push(const type &data);

    // 出栈(保存数据)
    virtual bool Pop(type &data);

    // 出栈（不保存数据）
    virtual bool Pop();

    // 获取栈顶元素
    virtual bool Top(type &data);

    // 判断栈是否为空
    virtual bool IsEmpty();

    // 获取栈的大小
    virtual int Length();

private:
    type *m_data;  // 元素数组
    int m_capacity;// 容量
    int m_top;     // 栈顶下标
};

// 析构函数
template<typename type>
SeqStack<type>::~SeqStack() {
    delete[] this->m_data;
}

// 入栈
template<typename type>
bool SeqStack<type>::Push(const type &data) {
    // 非法处理
    if (IsFull()) {
        return false;
    }

    this->m_top++;
    this->m_data[this->m_top] = data;

    return true;
}

// 元素出栈（保存数据）
template<typename type>
bool SeqStack<type>::Pop(type &data) {
    // 非法处理
    if (IsEmpty()) {
        return false;
    }

    data = this->m_data[m_top];
    this->m_top--;

    return true;
}

// 出栈（不保存数据）
template<typename type>
bool SeqStack<type>::Pop() {
    // 非法处理
    if (IsEmpty()) {
        return false;
    }

    this->m_top--;

    return true;
}

// 获取栈顶元素
template<typename type>
bool SeqStack<type>::Top(type &data) {
    // 非法处理
    if (IsEmpty()) {
        return false;
    }

    data = this->m_data[this->m_top];

    return true;
}

// 判断栈空
template<typename type>
bool SeqStack<type>::IsEmpty() {
    return this->m_top == -1;
}

// 判断栈满
template<typename type>
bool SeqStack<type>::IsFull() const {
    return this->m_top == this->m_capacity - 1;
}

// 获取栈大小
template<typename type>
int SeqStack<type>::Length() {
    return this->m_top + 1;
}

// 清空栈
template<typename type>
void SeqStack<type>::Clear() {
    int length = Length();
    if (length == 0) {
        return;
    }

    for (int i = 0; i < length; i++) {
        Pop();
    }
}

// 重载<< 运算符
template<typename TData>
std::ostream &operator<<(std::ostream &os, SeqStack<TData> &seq_stack) {

    os << "栈中元素个数: " << seq_stack.Length() << std::endl;

    for (int i = seq_stack.m_top; i >= 0; i--) {
        os << seq_stack.m_data[i] << std::endl;
    }

    return os;
}


#endif// _STACK_SEQSTACK_H_